package com.leyou.item.service;

import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exception.LeYouException;
import com.leyou.item.mapper.SpecGroupMapper;
import com.leyou.item.mapper.SpecParamMapper;
import com.leyou.item.pojo.SpecGroup;
import com.leyou.item.pojo.SpecParam;
import com.leyou.item.vo.SpecGroupDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @Author: Rose
 * @Date: 2021/2/14 16:23
 * @version: 1.0.0
 */
@Slf4j
@Transactional(rollbackFor = Exception.class)
@Service
public class SpecificationService {


    @Autowired
    private SpecGroupMapper specGroupMapper;

    @Autowired
    private SpecParamMapper paramMapper;


    /**
     * 根据分类cid 查询规格组
     *
     * @param cid
     * @return
     */
    public List<SpecGroup> queryGroupByCid(Long cid) {

        SpecGroup specGroup = new SpecGroup();
        specGroup.setCid(cid);
        List<SpecGroup> groupList = specGroupMapper.select(specGroup);

        if (CollectionUtils.isEmpty(groupList)) {
            // 未查询到数据
            throw new LeYouException(ExceptionEnum.SPECGROUP_NOT_FOUND);
        }

        return groupList;
    }

    /**
     * 根据商品分类id 添加规格组
     *
     * @param cid
     * @param name
     */
    public void addGroupByCid(Long cid, String name) {
        log.info("入参为：cid = {} , name =  {}", cid, name);
        // 非空校验
        if (StringUtils.isEmpty(name)) {
            throw new LeYouException(ExceptionEnum.SPECGROUP_NAME_ISNULL);
        }
        // cid 非空判断
        if (cid == null || cid.longValue() <= 0) {
            throw new LeYouException(ExceptionEnum.SPECGROUP_CID_ISNULL);
        }

        SpecGroup group = new SpecGroup();
        group.setCid(cid);
        group.setName(name);

        List<SpecGroup> select = specGroupMapper.select(group);
        // 判断是否已经存在
        if (!CollectionUtils.isEmpty(select)) {
            throw new LeYouException(ExceptionEnum.SPECGROUP_NAME_EXISTS);
        }

        int insert = specGroupMapper.insert(group);

        if (insert != 1) {
            throw new LeYouException(ExceptionEnum.SPECGROUP_CREATED_FAIL);
        }

    }

    /**
     * 根据 cid 和 id 修改 规格组名称
     *
     * @param cid
     * @param name
     * @param id
     */
    public void updateGroupByCid(Long cid, String name, Long id) {

        // 非空校验
        if (StringUtils.isEmpty(name)) {
            throw new LeYouException(ExceptionEnum.SPECGROUP_NAME_ISNULL);
        }
        // cid 非空判断
        if (cid == null || cid.longValue() <= 0) {
            throw new LeYouException(ExceptionEnum.SPECGROUP_CID_ISNULL);
        }
        if (id == null || id.longValue() <= 0) {
            throw new LeYouException(ExceptionEnum.SPECGROUP_ID_ISNULL);
        }

        SpecGroup specGroup = new SpecGroup();

        specGroup.setId(id);

        specGroup.setCid(cid);

        // 先查询
        List<SpecGroup> select = specGroupMapper.select(specGroup);
        // 先判断是否存在
        if (CollectionUtils.isEmpty(select)) {
            throw new LeYouException(ExceptionEnum.SPECGROUP_NOT_EXISTS);
        }
        // 设置 规格组的名称
        specGroup.setName(name);

        // 根据主键id 更新有内容的字段
        int result = specGroupMapper.updateByPrimaryKeySelective(specGroup);

        if (result != 1) {
            throw new LeYouException(ExceptionEnum.SPECGROUP_UPDATED_FAIL);
        }
    }

    /**
     * 根据规格组的主键ID 删除
     *
     * @param id
     */
    public void deleteGroupById(Long id) {

        // 判断是否已经存在
        SpecGroup specGroup = specGroupMapper.selectByPrimaryKey(id);
        if (specGroup == null) {
            throw new LeYouException(ExceptionEnum.SPECGROUP_NOT_FOUND);
        }

        // 根据主键 id 删除
        int result = specGroupMapper.deleteByPrimaryKey(id);

        if (result != 1) {
            throw new LeYouException(ExceptionEnum.SPECGROUP_DELETED_FAIL);
        }

    }


    /**
     * 根据组id 查询参数
     *
     * @param gid 组id
     * @return
     */
    public List<SpecParam> queryParamByGid(Long gid) {

        if (gid == null) {
            throw new LeYouException(ExceptionEnum.SPECPARAM_GID_ISNULL);
        }

        SpecParam specParam = new SpecParam();
        specParam.setGroupId(gid);

        List<SpecParam> specParamList = paramMapper.select(specParam);

        if (CollectionUtils.isEmpty(specParamList)) {
            throw new LeYouException(ExceptionEnum.SPECPARAM_NOT_FOUND);
        }

        return specParamList;
    }

    /**
     * 保存 规格参数
     *
     * @param cid
     * @param groupId
     * @param segments
     * @param numeric
     * @param searching
     * @param generic
     * @param name
     * @param unit
     */
    public void saveParam(Long cid, Long groupId, String segments, Boolean numeric, Boolean searching, Boolean generic, String name, String unit) {

        SpecParam specGroup = new SpecParam();
        //
        if (cid == null || cid.longValue() <= 0) {
            throw new LeYouException(ExceptionEnum.SPECGROUP_CID_ISNULL);
        }
        //
        if (groupId == null || groupId.longValue() <= 0) {
            throw new LeYouException(ExceptionEnum.SPECPARAM_GID_ISNULL);
        }
        // 名称为空
        if (StringUtils.isBlank(name)) {
            throw new LeYouException(ExceptionEnum.SPECPARAM_NAME_ISNULL);
        }
        // 是否是数字类型参数
        if (numeric == null) {
            throw new LeYouException(ExceptionEnum.SPECPARAM_NUMERIC_ISNULL);
        }
        // true
        if (numeric.booleanValue()) {
            // 判断数字类型的单位
            if (StringUtils.isBlank(unit)) {
                throw new LeYouException(ExceptionEnum.SPECPARAM_NNIT_ISNULL);
            }
        }

        specGroup.setCid(cid);
        specGroup.setGroupId(groupId);
        specGroup.setSegments(segments);
        specGroup.setNumeric(numeric);
        specGroup.setSearching(searching);
        specGroup.setGeneric(generic);
        specGroup.setName(name);
        specGroup.setUnit(unit);

        int insert = paramMapper.insert(specGroup);

        if (insert != 1) {
            throw new LeYouException(ExceptionEnum.SPECPARAM_CREATED_FAIL);
        }

    }

    /**
     * 更新商品 规格参数
     *
     * @param cid       商品分类id
     * @param groupId   商品规格组id
     * @param segments
     * @param numeric
     * @param searching
     * @param generic
     * @param name
     * @param unit
     */
    public void updateParam(Long id, Long cid, Long groupId, String segments, Boolean numeric, Boolean searching, Boolean generic, String name, String unit) {

        SpecParam specGroup = new SpecParam();

        if (id == null || id.longValue() <= 0) {
            throw new LeYouException(ExceptionEnum.SPECPARAM_ID_ISNULL);
        }
        //
        if (cid == null || cid.longValue() <= 0) {
            throw new LeYouException(ExceptionEnum.SPECGROUP_CID_ISNULL);
        }
        //
        if (groupId == null || groupId.longValue() <= 0) {
            throw new LeYouException(ExceptionEnum.SPECPARAM_GID_ISNULL);
        }
        // 名称为空
        if (StringUtils.isBlank(name)) {
            throw new LeYouException(ExceptionEnum.SPECPARAM_NAME_ISNULL);
        }
        // 是否是数字类型参数
        if (numeric == null) {
            throw new LeYouException(ExceptionEnum.SPECPARAM_NUMERIC_ISNULL);
        }
        // true
        if (numeric.booleanValue()) {
            // 判断数字类型的单位
            if (StringUtils.isBlank(unit)) {
                throw new LeYouException(ExceptionEnum.SPECPARAM_NNIT_ISNULL);
            }
        }

        SpecParam specParams = new SpecParam();
        specParams.setCid(cid);
        specParams.setGroupId(groupId);
        List<SpecParam> specParamList = paramMapper.select(specParams);

        specGroup.setId(id);
        specGroup.setCid(cid);
        specGroup.setGroupId(groupId);
        specGroup.setSegments(segments);
        specGroup.setNumeric(numeric);
        specGroup.setSearching(searching);
        specGroup.setGeneric(generic);
        specGroup.setName(name);
        specGroup.setUnit(unit);

        int insert = paramMapper.updateByPrimaryKey(specGroup);

        if (insert != 1) {
            throw new LeYouException(ExceptionEnum.SPECPARAM_CREATED_FAIL);
        }
    }


    /**
     * 根据主键 id 删除
     *
     * @param id
     */
    public void deleteSpecParamById(Long id) {
        if (id == null || id.longValue() <= 0) {
            throw new LeYouException(ExceptionEnum.SPECPARAM_ID_ISNULL);
        }
        int key = paramMapper.deleteByPrimaryKey(id);

        if (key != 1) {
            throw new LeYouException(ExceptionEnum.SPECPARAM_DELETED_FAIL);
        }
    }

    /**
     * @param gid
     * @param cid
     * @param searching
     * @return
     */
    public List<SpecParam> queryParamList(Long gid, Long cid, Boolean searching) {

        if (gid == null && cid == null && searching == null) {
            throw new LeYouException(ExceptionEnum.SPECPARAM_PARAM_ISNULL);
        }

        SpecParam specParam = new SpecParam();

        if (gid != null) {
            specParam.setGroupId(gid);
        }

        if (cid != null) {
            specParam.setCid(cid);
        }

        if (searching != null) {
            specParam.setSearching(searching);
        }

        List<SpecParam> specParamList = paramMapper.select(specParam);

        if (CollectionUtils.isEmpty(specParamList)) {
            throw new LeYouException(ExceptionEnum.SPECPARAM_NOT_FOUND);
        }
        return specParamList;
    }

    /**
     * @param cid
     * @return
     */
    public List<SpecGroupDTO> querySpecGroupByCid(Long cid) {
        // 查询规格组
        List<SpecGroup> specGroups = queryGroupByCid(cid);
        List<SpecGroupDTO> specGroupsDTOList = new ArrayList<>();
        // 查询当前分类下的参数
        List<SpecParam> specParams = queryParamList(null, cid, null);
        // 先把规格参数变成map, map的key 是规格组id, map的值时组下的所有参数
        Map<Long, List<SpecParam>> params = new HashMap<>();
        for (SpecParam specParam : specParams) {
            // 这个组 id 在params 中不存在， 新增一个List
            if (!params.containsKey(specParam.getGroupId())) {
                params.put(specParam.getGroupId(), new ArrayList<>());
            }
            List<SpecParam> specParamList = params.get(specParam.getGroupId());
            specParamList.add(specParam);

        }

        for (SpecGroup specGroup : specGroups) {
            SpecGroupDTO specGroupDTO = new SpecGroupDTO();
            BeanUtils.copyProperties(specGroup, specGroupDTO);
            specGroupDTO.setParams(params.get(specGroup.getId()));
            specGroupsDTOList.add(specGroupDTO);
        }
        return specGroupsDTOList;
    }
}
